
/*********************************************************
 *
 *  Project:      FlashCardsHZ
 *
 *  Class:        HZAccessor
 *
 *  File name:    HZAccessor.java
 *
 *  Parent class:
 *
 *********************************************************/

package com.eastmountain.chinese.db.flashcards.access;

import java.io.PrintWriter;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.eastmountain.chinese.db.exceptions.DBAccessException;
import com.eastmountain.chinese.db.flashcards.connection.DBAccessData;
import com.eastmountain.util.db.DBUtils;
import com.eastmountain.util.logging.LoggerUtils;

/*************************************************
 *
 *   CLASS - HZAccessor
 *
 ************************************************/

public abstract class HZAccessor {

    protected DBAccessData dbURLs;

    protected Connection flashCardDBConnection = null;
    protected Connection unihanDBConnection    = null;

    //  TODO is above used? - unihanDBConnection
    
    protected String tableName;

    protected static String LESSONS      = "LESSONS";
    protected static String WORDS        = "WORDS";
    protected static String WORDXRF      = "WORDXRF";
    protected static String CHARACTERS   = "CHARACTERS";
    protected static String CHARACTERXRF = "CHARACTERXRF";

    public static int DB2_DB_MANAGER   = 1;
    public static int DERBY_DB_MANAGER = 2;

    private int dbManager = DB2_DB_MANAGER;

    // tracing

    private static String printWriterName
        = "db\\derby.log";

    private static PrintWriter printWriter;

    private static String projectName = "hzaccessor";
    protected static Logger logger = LoggerUtils.setUpLogger( projectName );

    public HZAccessor( DBAccessData dbURLs ) throws DBAccessException {

        logger.setLevel( Level.SEVERE );
        
        this.dbURLs = dbURLs;

        boolean conectionsCreated = false;

        try {

            conectionsCreated
                = establishDBConnection( dbURLs );

            if ( conectionsCreated ) {

                setupPreparedStatements();

            }

        } catch ( DBAccessException dbAccessException ) {

            throw dbAccessException;

        } catch ( java.lang.Exception e ) {

            logger.log( Level.SEVERE, " *** Unexpected Exception: " + e.getClass().getName(), e );

        }

    }

    /*************************************************
     *
     *   setupPreparedStatements
     *
     ************************************************/

    abstract protected void setupPreparedStatements() throws DBAccessException;

    /*************************************************
     *
     *   establishDBConnection
     *
     ************************************************/

    private boolean establishDBConnection( DBAccessData dbURLs ) throws DBAccessException {
        
        boolean conectionsCreated = false;

        flashCardDBConnection = null;

        logger.info( ">>>>> establishDBConnection() called" );

        try {

            logger.info( " *** About to connect to: "
                          + dbURLs.getFLASHCARD_SOURCE_TEXT() );

            logger.info( " *** DB Driver: " + dbURLs.getDERBY_JDBC_DRIVER_NAME() );

            Class.forName( dbURLs.getDERBY_JDBC_DRIVER_NAME() ).newInstance();

            logger.info( " *** DB URL: " + dbURLs.getDATA_DB_URL() );
            logger.info( " *** About to connect to: " + dbURLs.getDATA_DB_URL() );

            flashCardDBConnection = DriverManager.getConnection( dbURLs.getDATA_DB_URL() );

            DBUtils.displayDBInfo( flashCardDBConnection );

            logger.info( " *** Got FlashCard DB Connection: " + flashCardDBConnection.toString() );

            // set up tracing

            printWriter = new PrintWriter( printWriterName );
            DriverManager.setLogWriter( printWriter );

            conectionsCreated = true;

        } catch ( ClassNotFoundException e ) {

            logger.log( Level.SEVERE, "ClassNotFoundException: "
                                      + e.getMessage() + "\n" 
                                      + "DB Driver Missing: "
                                      + dbURLs.getDERBY_JDBC_DRIVER_NAME()
                                      + " in HZAccessor.establishDBConnection()");

            System.exit( 12 );
            
        } catch ( java.lang.Exception e ) {


            logger.log( Level.SEVERE, "Unexpected Exception: "
                                      + e.getMessage() + "\n" 
                                      + "Possibly DB Driver Missing: "
                                      + dbURLs.getDERBY_JDBC_DRIVER_NAME()
                                      + " in HZAccessor.establishDBConnection()");

            System.exit( 12 );

        }

        return( conectionsCreated );

    }

    /*************************************************
     *
     *   shutdownDB
     *
     ************************************************/

    public boolean shutdownDB() throws DBAccessException {

        boolean ok = false;

        try {

            if ( ! flashCardDBConnection.isClosed() ) {

                flashCardDBConnection.close();
                flashCardDBConnection = null;

                DriverManager.getConnection( dbURLs.getDERBY_SHUTDOWN() );    

                System.out.println( "\n*****   DB shutdown complete   *****" );

                ok = true;

            } else {

                ok = false;

            }

        } catch ( SQLException e ) {

            // Test for the good exception

            ok = false;

        }

        return( ok );

    }
    
}
